package com.ruicar.afs.cloud.afscase.approvetask.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.afscase.approvetask.condition.WorkTaskPoolCondition;
import com.ruicar.afs.cloud.afscase.approvetask.entity.CaseApproveRecord;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkTaskPool;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkTaskPoolHistory;
import com.ruicar.afs.cloud.afscase.approvetask.mapper.WorkTaskPoolHistoryMapper;
import com.ruicar.afs.cloud.afscase.approvetask.service.CaseApproveRecordService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolHistoryService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.approvetask.vo.ApproveTaskVo;
import com.ruicar.afs.cloud.afscase.approvetask.vo.TaskHistoryContent;
import com.ruicar.afs.cloud.afscase.approvetask.vo.TaskHistoryVO;
import com.ruicar.afs.cloud.afscase.common.utils.DicUtils;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.processor.enums.NormalSubmitType;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Description 审批任务历史service实现
 * @Author Peng_Jinbo
 * @Date 2020/06/02 10:53
 */
@Service
@AllArgsConstructor
public class WorkTaskPoolHistoryServiceImpl extends ServiceImpl<WorkTaskPoolHistoryMapper, WorkTaskPoolHistory>
        implements WorkTaskPoolHistoryService {

    private CaseApproveRecordService caseApproveRecordService;
    private WorkTaskPoolService workTaskPoolService;

    /**
     * @Description 获取信贷分析中历史审批内容
     * 1. 暂存后页面重新加载后自动带入
     * 2. 改派后，改派前的暂存内容自动带入到改派后的信贷报告中
     * 3  退回
     *      A ： 退回经销商后重新提上来之后需要自动带入退回的操作员的信贷分析报告，报告上方不显示
     *      B ： （废弃）审批退回，如若退回后被代理人接收，那么当前信贷报告上方需要显示原处理人报告，提交后删除原处理人报告，组长处仅显示最新的
     * 4. 附条件核准，附条件核准时提交至终审时，除remark字段，其他字段需要自动带入当前信贷分析报告中 (已在前端处理)
     *
     * ****************************
     * 这里到处都是雷....... 慎重慎重慎重修改................
     * 逻辑已经理不清了，修改的部分仅仅是在打补丁维持功能正常使用
     *
     * @Author Peng_Jinbo
     * @Date 2020/6/6 16:35
     */
    @Override
    public TaskHistoryVO listHistoryContent(String stageId) {
        if(StrUtil.isBlank(stageId)) return TaskHistoryVO.builder().build();

        List<WorkTaskPoolHistory> taskHistories = super.list(Wrappers.<WorkTaskPoolHistory>lambdaQuery()
                .eq(WorkTaskPoolHistory::getStageId, stageId)
                .orderByDesc(WorkTaskPoolHistory::getCreateTime));

        List<TaskHistoryContent> contents = new ArrayList(taskHistories.size());
        TaskHistoryVO taskHistoryVO = TaskHistoryVO.builder().taskHistories(contents).build();
        List<WorkTaskPoolHistory> reformistHistories = new ArrayList<>();
        boolean lastIsReformist = true;
        if (CollectionUtil.isNotEmpty(taskHistories)) {
            Map<String, List<DicDataDto>> dicMaps = DicHelper.getDicMaps(AfsEnumUtil.key(DicKeyEnum.APPROVE_SUGGEST));
            boolean lastIsCallBack = false;
            List<WorkTaskPoolHistory> returnHistories = new ArrayList<>();
            for (int i = 0; i < taskHistories.size(); i++) {
                WorkTaskPoolHistory taskHistory = taskHistories.get(i);
                String historySuggest = taskHistory.getApproveSuggest();
                if(i == 0){
                    if(StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.REFORMIST))) {
                        taskHistoryVO.setLastOprIsReformist(true);
                    }else if(StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.SEND_BACK_TO_DEALER))
                        || StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.SEND_BACK))
                        || StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.CALL_BACK))){
                        taskHistoryVO.setLastOprIsReformist(true);
                        String remainJsonStr = taskHistory.getRemainData();
                        // 撤回时取撤回前一步操作的信贷分析报告,撤回前操作一定为流程提交操作
                        if(StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.SEND_BACK))
                                 || (StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.CALL_BACK))) && taskHistories.size() > 1){
                            int j = i;
                            WorkTaskPoolHistory prev = taskHistory;
                            HashSet<String> goOnPrevSubmitTypeSet = new HashSet<>();
                            goOnPrevSubmitTypeSet.add(AfsEnumUtil.key(NormalSubmitType.CALL_BACK));
                            goOnPrevSubmitTypeSet.add(AfsEnumUtil.key(NormalSubmitType.SEND_BACK));
                            goOnPrevSubmitTypeSet.add(AfsEnumUtil.key(NormalSubmitType.REFORMIST));
                            while (j++ < taskHistories.size() && goOnPrevSubmitTypeSet.contains(prev.getApproveSuggest())){
                                prev = taskHistories.get(j);
                                // 上一此操作为退回时，获取已删除的非退回记录
                                if(AfsEnumUtil.key(NormalSubmitType.SEND_BACK).equals(prev.getApproveSuggest())){
                                    List<WorkTaskPoolHistory> currentDelHis = baseMapper
                                            .listAlreadyDelTaskHistory(prev.getTaskNodeId(),prev.getStageId());
                                    if(CollectionUtil.isNotEmpty(currentDelHis)) {
                                        int index = 0;
                                        WorkTaskPoolHistory lastDelHis = currentDelHis.get(index);
                                        if(!AfsEnumUtil.key(NormalSubmitType.SEND_BACK).equals(lastDelHis.getApproveSuggest())){
                                            prev = lastDelHis;
                                            returnHistories.add(prev);
                                        }
                                    }
                                    break;
                                }
                            }
                            remainJsonStr = goOnPrevSubmitTypeSet.contains(prev.getApproveSuggest()) ? "" : prev.getRemainData();
                        }
                        if(StrUtil.isNotBlank(remainJsonStr)){
                            JSONObject remainJson = JSONObject.parseObject(remainJsonStr);
                            if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.RECORD))) {
                                CaseApproveRecord record = JSONObject.parseObject(
                                        remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(), CaseApproveRecord.class);
                                if(Objects.nonNull(record)){
                                    lastIsCallBack = StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.CALL_BACK));
                                    if( lastIsCallBack
                                        || (StrUtil.equals(record.getApproveSuggest(),AfsEnumUtil.key(NormalSubmitType.SUGGEST_CONDITION_FINAL))
                                                || StrUtil.equals(record.getApproveSuggest(),AfsEnumUtil.key(NormalSubmitType.SUGGEST_CONDITION)))) {
                                        taskHistoryVO.setBeforeReformistContent(
                                                TaskHistoryContent.builder()
                                                        .approveReason(record.getApproveReason())
                                                        .approveMessage(record.getApproveMessage())
                                                        .approveSuggest(record.getApproveSuggest())
                                                        .approveRemark(record.getApproveRemark())
                                                        .build()
                                        );
                                    }else {
                                        taskHistoryVO.setBeforeReformistContent(
                                                TaskHistoryContent.builder()
                                                        .approveRemark(record.getApproveRemark())
                                                        .build()
                                        );
                                    }
                                }
                            }
                        }
                        continue;
                    }
                }else{
                    if(!StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.REFORMIST))){
                        lastIsReformist = false;
                    }
                }
                if(StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.SEND_BACK))
                        || StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.SEND_BACK_TO_DEALER))
                        || StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.MODIFY_SUBMIT))
                        || StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.CALL_BACK))){
                    lastIsCallBack = false;
                    continue;
                }else if(StrUtil.equals(historySuggest,AfsEnumUtil.key(NormalSubmitType.REFORMIST))){
                    if(lastIsReformist) {
                        reformistHistories.add(taskHistory);
                    }
                } else if(!lastIsCallBack) {
                    returnHistories.add(taskHistory);
                }
                lastIsCallBack = false;
            }

            if(taskHistoryVO.isLastOprIsReformist() && Objects.isNull(taskHistoryVO.getBeforeReformistContent())){
                for (WorkTaskPoolHistory reformistHistory : reformistHistories) {
                    if(Objects.nonNull(taskHistoryVO.getBeforeReformistContent())){
                        break;
                    }
                    String remainJsonStr = reformistHistory.getRemainData();
                    if(StrUtil.isNotBlank(remainJsonStr)){
                        JSONObject remainJson = JSONObject.parseObject(remainJsonStr);
                        if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.BEFORE_REFORMIST_RECORD))) {
                            CaseApproveRecord record = JSONObject.parseObject(
                                    remainJson.get(AfsEnumUtil.key(RemainKeyEnum.BEFORE_REFORMIST_RECORD)).toString(), CaseApproveRecord.class);
                            if(Objects.nonNull(record)){
                                taskHistoryVO.setBeforeReformistContent(
                                        TaskHistoryContent.builder()
                                                .approveMessage(record.getApproveMessage())
                                                .approveRemark(record.getApproveRemark())
                                                .approveSuggest(record.getApproveSuggest())
                                                .approveReason(record.getApproveReason())
                                                .build()
                                );
                            }
                        }
                    }
                }
            }

            for (WorkTaskPoolHistory taskHistory : returnHistories) {
                TaskHistoryContent content = TaskHistoryContent.builder().build();
                StringBuffer title = new StringBuffer();
                title.append(taskHistory.getApproveStaffName());
                String remainJsonStr = taskHistory.getRemainData();
                if (StrUtil.isNotBlank(remainJsonStr)) {
                    JSONObject remainJson = JSONObject.parseObject(remainJsonStr);
                    if (remainJson.containsKey(AfsEnumUtil.key(RemainKeyEnum.RECORD))) {
                        CaseApproveRecord record = JSONObject.parseObject(
                                remainJson.get(AfsEnumUtil.key(RemainKeyEnum.RECORD)).toString(), CaseApproveRecord.class);
                        if (Objects.nonNull(record)) {
                            title.append(DicUtils.translate(record.getApproveSuggest(), dicMaps));
                            title.append(DateUtil.format(taskHistory.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
                            content.setTitle(title.toString());
                            content.setContent(record.getApproveRemark());
                            content.setApproveSuggest(taskHistory.getApproveSuggest());
                            content.setApproveReason(Convert.toStr(record.getApproveReason(), ""));
                            content.setApproveMessage(record.getApproveMessage());
                            content.setApproveRemark(record.getApproveRemark());
                            contents.add(content);
                        }
                    }
                }
            }
        }
        if(taskHistoryVO.isLastOprIsReformist() && Objects.isNull(taskHistoryVO.getBeforeReformistContent())){
            taskHistoryVO.setLastOprIsReformist(false);
        }
        return taskHistoryVO;
    }

    /**
     * @description: 经我处理
     * @author jiaqi.guo
     * @created 2020/7/11 16:20
     * @version 1.0
     */
    public IPage<ApproveTaskVo> queryDealWithTaskList(Page page, WorkTaskPoolCondition workTaskPoolCondition) {
        return baseMapper.queryDealWithTaskList(page, workTaskPoolCondition);
    }

    /**
     * <p>description：</p>
     * 撤回校验
     * @param caseBaseInfo 案件基本信息
     * @param stageId 流程实例表ID
     * @param callbackStaff 撤回申请人
     * @return 校验结果：  <br/>true: 可直接撤回；<br/> false：不可直接撤回
     * @Author ma_xueyu
     * @Date 2020年9月7日
     */
    @Override
    public boolean checkCallBackData(CaseBaseInfo caseBaseInfo,String stageId,String callbackStaff){
        boolean checkResult;
        //申请撤回的节点
        WorkTaskPoolHistory callbackWorkTaskHistory = this.list(Wrappers.<WorkTaskPoolHistory>query().lambda()
                .eq(WorkTaskPoolHistory::getApplyNo,caseBaseInfo.getApplyNo())
                .eq(WorkTaskPoolHistory::getProcessType, ProcessTypeEnum.GENERA_APPROVE.getCode())
                .eq(WorkTaskPoolHistory::getStageId,stageId)
                .eq(WorkTaskPoolHistory::getApproveStaff,callbackStaff)
                .orderByDesc(WorkTaskPoolHistory::getCreateTime)
        ).stream().findFirst().orElse(new WorkTaskPoolHistory());
        //审批结果：已核准
        if(AfsEnumUtil.key(BusinessStateInEnum.APPROVED).equals(caseBaseInfo.getBusinessStateIn())
                ||AfsEnumUtil.key(BusinessStateInEnum.CONDITIONAL_APPROVE).equals(caseBaseInfo.getBusinessStateIn())){
            //判断是否尾节点
            if(WhetherEnum.YES.getCode().equals(callbackWorkTaskHistory.getLastNode())){
                // 判断案件是否打印合同、申请放款
                List<CaseApproveRecord> recordList = caseApproveRecordService.list(Wrappers.<CaseApproveRecord>query().lambda()
                        .eq(CaseApproveRecord::getApplyNo,caseBaseInfo.getApplyNo())
                        .and(wrapper1 -> wrapper1.eq(CaseApproveRecord::getCurrentPosition,CurrentPositionEnum.GENERAL_LOAN)
                            .or(wrapper2 -> wrapper2.eq(CaseApproveRecord::getApproveSuggestName,"打印合同"))));
                if (CollectionUtil.isNotEmpty(recordList)){
                    throw new AfsBaseException("经销商正在打印合同或已提交放款申请，无法撤回");
                }else{
                    checkResult = true;
                }
            }else{
                throw new AfsBaseException("审批流程记录异常，无法撤回");
            }
        }else if(AfsEnumUtil.key(BusinessStateInEnum.REPEAL).equals(caseBaseInfo.getBusinessStateIn())
                ||AfsEnumUtil.key(BusinessStateInEnum.REJECT).equals(caseBaseInfo.getBusinessStateIn())){
            //其他审批结果
            throw new AfsBaseException("已产生审批结果，无法撤回");
        }else if(AfsEnumUtil.key(BusinessStateInEnum.REVISE_PARSE).equals(caseBaseInfo.getBusinessStateIn())){
            //修订-暂停
            checkResult = true;
        }else{//未出结果
            //查询申请撤回节点之后的任务历史记录
            List<WorkTaskPoolHistory> afterCallbackWorkTaskHistoryList = this.list(Wrappers.<WorkTaskPoolHistory>query().lambda()
                    .eq(WorkTaskPoolHistory::getApplyNo,caseBaseInfo.getApplyNo())
                    .eq(WorkTaskPoolHistory::getProcessType,ProcessTypeEnum.GENERA_APPROVE.getCode())
                    .eq(WorkTaskPoolHistory::getStageId,stageId)
                    .gt(WorkTaskPoolHistory::getCreateTime,callbackWorkTaskHistory.getCreateTime()));
            if(CollectionUtil.isNotEmpty(afterCallbackWorkTaskHistoryList) ){
                throw new AfsBaseException("不可跨节点撤回");
            }else{
                //再次判断下一节点待办人员是否打开任务
                WorkTaskPool nextWorkTask=workTaskPoolService.getNextWorkTaskByCondition(caseBaseInfo.getApplyNo(),stageId,callbackStaff);
                if(WhetherEnum.YES.getCode().equals(nextWorkTask.getIsOpen())){
                    checkResult = false;
                }else{
                    checkResult = true;
                }
            }
        }
        return checkResult;
    }

    /**
     * 查询部长全部的退回意见
     * @param applyNo
     * @param stageId
     * @param currentNodeId
     * @return
     */
    @Override
    public List<WorkTaskPoolHistory> queryAllData(String applyNo, String stageId, String currentNodeId) {
        return baseMapper.queryAllData(applyNo,stageId,currentNodeId);
    }

    public List<WorkTaskPoolHistory> findAllData(String applyNo, String stageId, String currentNodeId) {
        return baseMapper.findAllData(applyNo,stageId,currentNodeId);
    }
}
